
#include <stdio.h>
#include <string.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")

#include "FileMD5.h"
#include "cdcsyncFileSrcBlocksInfo.h"
#include "cdcsyncSrc.h";

#define WINDOWS_SIZE 1024
#define D 1024
#define R 1024


int cdcsync_server(const char* ip, unsigned short port, char filename[100]){
	int now_version = 0;
	char now_version_filename[100];
	strcpy(now_version_filename, filename);
	WSADATA wsaData;
	int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
	if (iResult != NO_ERROR) {
		wprintf(L"WSAStartup failed with error: %ld\n", iResult);
		return 1;
	}
	//----------------------
	// Create a SOCKET for listening for
	// incoming connection requests.
	SOCKET ListenSocket;
	ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (ListenSocket == INVALID_SOCKET) {
		wprintf(L"socket failed with error: %ld\n", WSAGetLastError());
		WSACleanup();
		return 1;
	}
	//----------------------
	// The sockaddr_in structure specifies the address family,
	// IP address, and port for the socket that is being bound.
	sockaddr_in service;
	service.sin_family = AF_INET;
	service.sin_addr.s_addr = inet_addr(ip);
	service.sin_port = htons(port);
	if (bind(ListenSocket,
		(SOCKADDR *) & service, sizeof (service)) == SOCKET_ERROR) {
			wprintf(L"bind failed with error: %ld\n", WSAGetLastError());
			closesocket(ListenSocket);
			WSACleanup();
			return 1;
	}
	//----------------------
	// Listen for incoming connection requests.
	// on the created socket
	if (listen(ListenSocket, 1) == SOCKET_ERROR) {
		wprintf(L"listen failed with error: %ld\n", WSAGetLastError());
		closesocket(ListenSocket);
		WSACleanup();
		return 1;
	}
	//----------------------
	// Create a SOCKET for accepting incoming requests.
	SOCKET AcceptSocket;
	wprintf(L"Waiting for client to connect...\n");
	//----------------------
	// Accept the connection.
	while(true){
		AcceptSocket = accept(ListenSocket, NULL, NULL);
		if (AcceptSocket == INVALID_SOCKET) {
			wprintf(L"accept failed with error: %ld\n", WSAGetLastError());
			closesocket(ListenSocket);
			WSACleanup();
			return 1;
		} else
			wprintf(L"Client connected.\n");

		md5_byte_t md5_file[16];
		FILE* fp;
		unsigned long file_size;
		FileSrcBlocksInfo_cdcsync fbi;

		fp = fopen(now_version_filename, "r");
		initAndBuildFileSrcBlocksInfo_cdcsync(fbi, fp, WINDOWS_SIZE,D, R);

		sendBlocksInfo(AcceptSocket, fbi);
		FILE* wirte_fp;
		char now_version_str[4];
		strcpy(now_version_filename, filename);
		strcat(now_version_filename, "_R");
		strcat(now_version_filename, itoa(++now_version, now_version_str, 10));
		wirte_fp = fopen(now_version_filename, "ab");
		recvyncInfo(AcceptSocket, fbi, fp, wirte_fp);
		fclose(wirte_fp);
		fclose(fp);
	}
	closesocket(ListenSocket);
	WSACleanup();
	return 0;
}